﻿namespace DCHealthCheck.MvcWeb.Classes.DataServices {

    #region Usings
    using DCHealthCheck.Common;
    using DCHealthCheck.DomainModel;
    using DCHealthCheck.MvcWeb.Classes.ViewModels;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading;
    using System.Web;
    #endregion

    public class GroupPolicySysvolInfoDataService : BaseDataService, IGroupPolicySysvolInfoDataService  {

        #region Members
        private readonly IRepository<GroupPolicySysvolInfo, IEntityManager> GroupPolicySysvolInfoRepository;

        private readonly Expression<Func<GroupPolicySysvolInfo, object>>[] GroupPolicySysvolInfoIncludedEntities;
        
        #endregion

        #region Constructor
        public GroupPolicySysvolInfoDataService(
            IRepository<DomainController, IEntityManager> dcRepository,
            IRepository<GroupPolicySysvolInfo, IEntityManager> groupPolicySysvolInfoRepository)
            : base(dcRepository) {
            if (groupPolicySysvolInfoRepository == null) {
                throw new ArgumentNullException("groupPolicySysvolInfoRepository");
            }
            this.GroupPolicySysvolInfoRepository = groupPolicySysvolInfoRepository;

            this.GroupPolicySysvolInfoIncludedEntities = new Expression<Func<GroupPolicySysvolInfo, object>>[] {
                (x) => x.SystemInfo,
                (x) => x.SystemInfo.DomainController,
                (x) => x.SystemInfo.HealthCheckSummary
            };
        }
        #endregion

        #region Methods
        public string GetCSVData(GroupPolicySysvolInfoViewModel viewModel) {

            viewModel.Initialize();
            viewModel.SkipCount = 0;
            viewModel.TakeCount = int.MaxValue;
            this.ProcessData(viewModel, false, false);

            var fileData = new StringBuilder();

            fileData.AppendLine(GroupPolicySysvolInfo.CSVHeader);
            foreach (var record in viewModel.GroupPolicySysvolInfos) {
                fileData.AppendLine(record.ToCSVString());
            }

            return fileData.ToString();
        }

        private IQueryable<GroupPolicySysvolInfo> GetFilteredGroupPolicySysvolInfos(GroupPolicySysvolInfoViewModel viewModel) {

            var groupPolicySysvolInfos = this.GroupPolicySysvolInfoRepository.Get(this.GroupPolicySysvolInfoIncludedEntities);

            if (viewModel.SystemInfoId != Guid.Empty) {
                groupPolicySysvolInfos = groupPolicySysvolInfos.Where(x => x.SystemInfo.Id == viewModel.SystemInfoId);
            }
            else {
                if (viewModel.DomainControllerId != Guid.Empty) {
                    groupPolicySysvolInfos = groupPolicySysvolInfos.Where(x => x.SystemInfo.DomainController.Id == viewModel.DomainControllerId);
                }

                if (viewModel.Date != DateTime.MinValue) {
                    groupPolicySysvolInfos = groupPolicySysvolInfos.Where(x => x.SystemInfo.CheckDateTimeUTC == viewModel.Date);
                }
                else {
                    if (viewModel.StartDate.HasValue) {
                        groupPolicySysvolInfos = groupPolicySysvolInfos.Where(x => x.SystemInfo.CheckDateUTC >= viewModel.StartDate);
                    }
                    if (viewModel.EndDate.HasValue) {
                        groupPolicySysvolInfos = groupPolicySysvolInfos.Where(x => x.SystemInfo.CheckDateUTC <= viewModel.EndDate);
                    }
                }

                if (!string.IsNullOrWhiteSpace(viewModel.ADSite)) {
                    groupPolicySysvolInfos = groupPolicySysvolInfos
                        .Where(x => x.SystemInfo.DomainController.ADSite == viewModel.ADSite);
                }
                if (!string.IsNullOrWhiteSpace(viewModel.Domain)) {
                    groupPolicySysvolInfos = groupPolicySysvolInfos
                        .Where(x => x.SystemInfo.DomainController.NetbiosDomain == viewModel.Domain);
                }
                if (!string.IsNullOrWhiteSpace(viewModel.OSVersion)) {
                    groupPolicySysvolInfos = groupPolicySysvolInfos
                        .Where(x => x.SystemInfo.DomainController.OSVersion == viewModel.OSVersion);
                }
                if (!string.IsNullOrWhiteSpace(viewModel.DCName)) {
                    groupPolicySysvolInfos = groupPolicySysvolInfos
                        .Where(x => x.SystemInfo.DomainController.SamAccountName == viewModel.DCName);
                }
            } // else if (this.SystemInfoId != Guid.Empty)

            return groupPolicySysvolInfos;
        }

        public void ProcessData(GroupPolicySysvolInfoViewModel viewModel, bool initialize = true, bool buildFilterSelectLists = true) {
            Global.DefaultLog.DebugFormat("[ThreadId: {0}] {1}", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName());

            try {
                if (initialize) {
                    viewModel.Initialize();
                }
                var groupPolicySysvolInfos = this.GetFilteredGroupPolicySysvolInfos(viewModel);
                viewModel.DisplayTotalResults = groupPolicySysvolInfos.Count();

                #region Skip count, take, and sorting
                if (!string.IsNullOrWhiteSpace(viewModel.SortColumn)) {
                    if (viewModel.CurrentSortDirection == System.Web.Helpers.SortDirection.Ascending) {
                        viewModel.GroupPolicySysvolInfos = groupPolicySysvolInfos
                            .OrderBy(viewModel.SortColumn)
                            .Skip(viewModel.SkipCount.Value)
                            .Take(viewModel.TakeCount.Value)
                            .ToList();
                    }
                    else {
                        viewModel.GroupPolicySysvolInfos = groupPolicySysvolInfos
                            .OrderByDescending(viewModel.SortColumn)
                            .Skip(viewModel.SkipCount.Value)
                            .Take(viewModel.TakeCount.Value)
                            .ToList();
                    }
                }
                else {
                    viewModel.GroupPolicySysvolInfos = groupPolicySysvolInfos
                        .OrderBy(x => x.SystemInfo.DomainController.SamAccountName)
                        .Skip(viewModel.SkipCount.Value)
                        .Take(viewModel.TakeCount.Value)
                        .ToList();
                }
                #endregion

                viewModel.GetPageCounts();
                if (buildFilterSelectLists) {

                    var filteredDCIds = this.GetFilteredGroupPolicySysvolInfos(viewModel)
                        .Select(x => x.SystemInfo.DomainController.Id)
                        .Distinct()
                        .ToList();
                    base.BuildFilterSelectLists(filteredDCIds, viewModel);
                }
            }
            catch (Exception e) {
                Global.DefaultLog.DebugFormat("[ThreadId: {0}] {1} {2}", Thread.CurrentThread.ManagedThreadId, Extensions.CurrentMethodName(), e.VerboseExceptionString());
            }
        } 
        #endregion

    }
}